﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoTime.ServiceContracts;
using CoTime.ServiceImpl;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace CoTime.DataAccess
{
    public class Repository<T>
    {
        #region [ Fields ]

        static readonly ILogger logger = new Logger();
        readonly String _file;
        readonly List<T> _items;

        #endregion

        #region [ Constructors ]
        
        private Repository() { }

        public Repository(String file)
            : this()
        {
            _file = file;
            _items = LoadItems();
        }

        #endregion

        #region [ Public Interface ]

        public event EventHandler<ItemAddedEventArgs<T>> ItemAdded;

        public void AddItem(T item)
        {
            if (item == null)
                throw new ArgumentNullException("item");

            if (!_items.Contains(item))
            {
                _items.Add(item);
                if (this.ItemAdded != null)
                    this.ItemAdded(this, new ItemAddedEventArgs<T>(item));
            }
            else
            {
                throw new ArgumentException("duplicate note");
            }
        }

        public void SetItem(List<T> items)
        {
            _items.Clear();
            _items.AddRange(items);
        }

        /// <summary>
        /// return a shallow-copied list of all notes in the repository
        /// </summary>
        /// <returns></returns>
        public List<T> GetItems()
        {
            return new List<T>(_items);
        }

        public void Save()
        {
            using (TextWriter writer = new StreamWriter(_file))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
                serializer.Serialize(writer, _items);
            }
        }

        #endregion

        #region [ Private Helpers ]

        private List<T> LoadItems()
        {
            List<T> data;
            using (FileStream fs = new FileStream(_file, FileMode.OpenOrCreate))
            {
                try
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
                    data = serializer.Deserialize(fs) as List<T>;
                }
                catch (InvalidOperationException E)
                {
                    data = new List<T>();
                    logger.Log(E.Message);
                }
                catch (XmlException E)
                {
                    data = new List<T>();
                    logger.Log(E.Message);
                }
            }
            return data;
        }

        #endregion
    }
}
